home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TPTUTR~1.ZIP / PASCAL15.TXT < prev    next >
Text File  |  1996-03-21  |  13KB  |  436 lines

  1.                        Turbo Pascal for DOS Tutorial
  2.                             by Glenn Grotzinger
  3.                    Part 15: Concepts of Sorting Arrays
  4.                 copyright (c) 1995-96 by Glenn Grotzinger
  5.  
  6. Here is a solution from last time...keep in mind to be as efficient as
  7. possible in coding...I figure that many will try simply writing those frames
  8. out.
  9.  
  10. program part14; uses crt;
  11.  
  12.   var
  13.     esccount: byte;
  14.     chr: char;
  15.  
  16.   procedure setitup;
  17.     begin
  18.       { green border of 4 units }
  19.       textbackground(green);
  20.       clrscr;
  21.       window(5,5, 76, 21);
  22.  
  23.       { red border of one unit }
  24.       textbackground(red);
  25.       clrscr;
  26.       window(6,6,75,20);
  27.  
  28.       { set up black background }
  29.       textbackground(black);
  30.       clrscr;
  31.  
  32.       { write keypress statement }
  33.       highvideo;
  34.       textcolor(lightcyan);
  35.       writeln('Keypress Detector (Press ESC 5 times to quit)');
  36.  
  37.       { preserve Keypress detector title. }
  38.       window(6,7,75,20);
  39.     end;
  40.  
  41.   function status(char1: char;var esccount: byte): string;
  42.     var
  43.       char2: char;
  44.     begin
  45.       if char1 = #0 then
  46.         begin
  47.           char2 := readkey;
  48.           case char2 of
  49.             #59: status := 'F1';
  50.             #60: status := 'F2';
  51.             #61: status := 'F3';
  52.             #62: status := 'F4';
  53.             #63: status := 'F5';
  54.             #64: status := 'F6';
  55.             #65: status := 'F7';
  56.             #66: status := 'F8';
  57.             #67: status := 'F9';
  58.             #68: status := 'F10';
  59.             #82: status := 'Insert';
  60.             #71: status := 'Home';
  61.             #73: status := 'PageUp';
  62.             #81: status := 'PageDown';
  63.             #83: status := 'Delete';
  64.             #79: status := 'End';
  65.             #77: status := 'Right';
  66.             #72: status := 'Up';
  67.             #80: status := 'Down';
  68.             #75: status := 'Left';
  69.           end;
  70.         end
  71.       else
  72.         case char1 of
  73.           #8: status := 'Backspace';
  74.           #9: status := 'TAB';
  75.           #13: status := 'ENTER';
  76.           #27: begin
  77.                  status := 'ESC';
  78.                  inc(esccount, 1);
  79.                  { the 1 is not required here, but the inc and dec
  80.                    functions can be used with values greater than
  81.                    one like this in this case }
  82.                end;
  83.           #32: status := 'SPACE';
  84.         else
  85.           status := char1;
  86.         end;
  87.     end;
  88.  
  89.   procedure endit;
  90.     var
  91.       i: byte;
  92.     begin
  93.       window(1,1,80,25);
  94.       gotoxy(1,1);
  95.       for i := 1 to 25 do
  96.         begin
  97.           delline;
  98.           delay(100);
  99.         end;
  100.     end;
  101.  
  102.   begin
  103.     esccount := 0;
  104.     setitup;
  105.  
  106.     while esccount <> 5 do
  107.       begin
  108.         chr := readkey;
  109.         normvideo;
  110.         textcolor(lightblue);
  111.         write('You pressed the ');
  112.         highvideo;
  113.         textcolor(green);
  114.         write(status(chr, esccount));
  115.         normvideo;
  116.         textcolor(lightblue);
  117.         writeln(' key.');
  118.       end;
  119.  
  120.     endit;
  121.   end.
  122. Now, we will discuss the use of sorting with regards to arrays into a
  123. particular order.  Sometimes we may need numbers, such as dates in
  124. chronological order, or a list of names in alphabetical order.
  125.  
  126. Swapping Units
  127. ==============
  128. The integral part of a sorting routine is a unit swap.  As a rule, we
  129. MUST have a temporary variable, because a simple assign set will not work.
  130.  
  131. For example, to swap the contents in variables a and b, we need a temporary
  132. variable we will call temp.  Then code such as what is below will do...
  133.  
  134. temp := b;
  135. b := a;
  136. a := temp;
  137.  
  138. The swap should ideally be performed with the smallest units possible,
  139. based on the sorting key.  The idea of a sorting key will be explained
  140. later.  You may end up using pointers to get it to move the smallest
  141. amount of data, which will be explained in a future part.  The less
  142. amount of data the computer can move, the better.
  143.  
  144. The BubbleSort (or the brute force sort)
  145. ========================================
  146. Basically, in this sorting method, each and every item in the array is
  147. compared each and every other item in the array.  This is a largely
  148. inefficient method for sorting items, but easy to code, and useful for
  149. small amounts of data.
  150.  
  151. program example_of_bubblesort;
  152.  
  153.   var
  154.     thearray: array[1..20] of integer;
  155.     temp: integer;
  156.     i, j: integer;
  157.  
  158.   begin
  159.     randomize;
  160.     { generate numbers for array and write them as unsorted }
  161.     write('The unsorted array: ');
  162.     for i := 1 to 20 do
  163.       begin
  164.         thearray[i] := random(50) + 1;
  165.         write(thearray[i], ' ');
  166.       end;
  167.     writeln;
  168.  
  169.     { the bubblesort. }
  170.     for i := 1 to 20 do
  171.       for j := i+1 to 20 do
  172.         if thearray[i] > thearray[j] then { compare and swap }
  173.           begin
  174.             temp := thearray[i];
  175.             thearray[i] := thearray[j];
  176.             thearray[j] := temp;
  177.           end;
  178.  
  179.     write('The sorted array: ');
  180.     for i := 1 to 20 do
  181.       write(thearray[i], ' ');
  182.     writeln;
  183.  
  184. end.
  185. As it is a purely iterative solution, you should have no exact trouble
  186. seeing what is going on.  But to further another point as to exactly
  187. how it works, and why it is so inefficient, we will sort a sample set
  188. of numbers manually according to this algorithm to see what is going on.
  189.  
  190. 1       3       2       5       4
  191.  
  192. We will start out with the following short description of what is going
  193. on within the two for loops for 5 values of data:
  194.  
  195. 1) i = 1; j = 2; Position1 = 1; Position2 = 3; 1 > 3 = false;
  196. 2) i = 1; j = 3; Position1 = 1; Position3 = 2; 1 > 2 = false;
  197. 3) i = 1; j = 4; Position1 = 1; Position4 = 5; 1 > 5 = false;
  198. 4) i = 1; j = 5; Position1 = 1; Position5 = 4; 1 > 4 = false;
  199.  
  200. 5) i = 2; j = 3; Position2 = 3; Position3 = 2; 3 > 2 = true; we swap the
  201. two values...so our resultant array is...
  202.  
  203. 1       2       3       5       4
  204.  
  205. 6) i = 2; j = 4; Position2 = 2; Position4 = 5; 2 > 5 = false;
  206. 7) i = 2; j = 5; Position2 = 2; Position5 = 4; 2 > 4 = false;
  207.  
  208. 8) i = 3; j = 4; Position3 = 3; Position4 = 5; 3 > 5 = false;
  209. 9) i = 3; j = 5; Position3 = 3; Position5 = 4; 3 > 4 = false;
  210.  
  211. 10) i = 4; j = 5; Position4 = 5; Position5 = 4; 5 > 4 = true; we swap
  212. the two values...so the resultant array is...
  213.  
  214. 1       2       3       4       5
  215.  
  216. 11) Effective termination of loop;
  217.  
  218. As we can see, we took 10 steps in the algorithm to swap 2 elements of
  219. the array in order to sort it.  Basically, this is a very inefficient
  220. algorithm in comparison to other types that are available, as we are
  221. considering portions of the array that are already sorted.  As a note,
  222. to sort the items in descending order instead of ascending order, change
  223. the comparison between the two positions i and j of the array from > to <.
  224.  
  225. QuickSort
  226. =========
  227. This is a much faster recursive solution for sorting than the bubblesort.
  228. It makes use of a pivot marker, which moves according to what exactly is
  229. contained in the array.  It also will make use of a "divide and conquer"
  230. approach.  Here is a short example...
  231.  
  232. program example_of_quicksort;
  233.  
  234.   var
  235.     thearray: array[1..20] of integer;
  236.     i, j, PIVOT, t: integer;
  237.  
  238.   procedure quicksort(L, R: integer);
  239.     begin
  240.       if L < R then
  241.         begin
  242.           i := L + 1;
  243.           j := R;
  244.           PIVOT := thearray[L];
  245.  
  246.           repeat
  247.             while thearray[i] <= PIVOT do inc(i);
  248.             while thearray[j] > PIVOT do dec(j);
  249.             if i < j then
  250.               begin
  251.                 t := thearray[i];
  252.                 thearray[i] := thearray[j];
  253.                 thearray[j] := t;
  254.               end;
  255.           until i > j;
  256.  
  257.           thearray[L] := thearray[j];
  258.           thearray[j] := PIVOT;
  259.  
  260.           quicksort(L, j-1);
  261.           quicksort(i, R);
  262.         end;
  263.     end;
  264.  
  265.   begin
  266.     randomize;
  267.     write('The unsorted array is: ');
  268.     for i := 1 to 20 do
  269.       begin
  270.         thearray[i] := random(50) + 1;
  271.         write(thearray[i], ' ');
  272.       end;
  273.  
  274.     quicksort(1, 20);
  275.  
  276.     write('The sorted array is: ');
  277.     for i := 1 to 20 do
  278.       write(thearray[i], ' ');
  279.   end.
  280.  
  281. This is a recursive solution, so it will be a little different.  Let's
  282. start with the same number sequence we had above and see how quicksort
  283. works...keep in mind that quicksort is about as inefficient as bubble-
  284. sort with smaller sets...Once you get into larger sets, quicksort beats
  285. bubblesort hands down -- it more intelligently seeks the proper array
  286. units to swap.
  287.  
  288. 1       3       2       5       4
  289.  
  290. 1) 1 < 5 = true so continue.... i = 2; j = 5; PIVOT = 4;
  291.    3 <= 4 = true so i = 3; 2 <= 4 = true so i = 4;
  292.    5 <= 4 = false so quit;
  293.  
  294.    4 > 5 so quit;
  295.    4 < 5 = true, so swap values.  The resulting swap is...
  296.  
  297. 1       3       2       4       5
  298.  
  299.    4 > 5 = false so continue on repeat loop...
  300.  
  301.    i = 4; j = 5; PIVOT = 4; 4 <= 4 = true so i = 5;
  302.    5 <= 4 = false so quit;
  303.  
  304.    5 > 4 = true so j = 4; 4 > 4 = false so quit;
  305.  
  306.    5 > 4 = true so quit repeat loop.
  307.  
  308.    j = 4; i = 5; 4 is left side. 4th element is 4.
  309.  
  310. 2) Quicksort called for left side of 1, and right side of 3.  Then quicksort
  311. for left side of 5, and right side of 5. Essentially, we keep cutting the
  312. array in half based by where the pivot lands.  We will process the quicksort
  313. for the left side as 2a) and the quicksort for the right side as 2b).
  314.  
  315. 2a) Our number set for this instance of quicksort is:
  316.  
  317. 1       3       2
  318.  
  319.     1 < 3 = true so continue.
  320.  
  321.     i = 2; j = 3; PIVOT = 2; 3 <= 2 = false so quit;
  322.     i = 2; j = 3; PIVOT = 2; 2 > 2 = false so quit;
  323.  
  324.     2 < 3 = true so swap values...the resulting swap is...
  325.  
  326. 1       2       3
  327.  
  328.     2 > 3 = false so quit repeat loop.
  329.  
  330.     Quicksort called twice for left side of 1, 2 and 2,3.  The results of
  331.     both of these sorts end up being false, so they will terminate
  332.     readily.
  333.  
  334.  
  335. 2b) 5 < 5 = false so terminate quicksort.
  336.  
  337.  
  338. As we can see, the algorithm sets itself up so it ignores portions of the
  339. array that are already sorted.  For larger arrays, it will provide a great
  340. performance boost as we are ignoring the parts of the array that happen
  341. to be sorted by using this particular algorithm.
  342.  
  343. The version of quicksort pictured sorts in ascending order.  To make it
  344. sort in descending order, change the two while loops to read the following:
  345.  
  346. while thearray[i] <= PIVOT do inc(i);
  347. while thearray[j] > PIVOT do dec(j);
  348.  
  349. ShellSort
  350. =========
  351. This is a non-recursive sort that performs close in performance to quicksort.
  352. We can follow what is going on, so I will just simply write an example of
  353. the use of the shellsort, and describe how to change it to sort in descending
  354. order instead of ascending order...
  355.  
  356. program example_of_shellsort;
  357.  
  358.   var
  359.     thearray: array[1..20] of integer;
  360.     i: integer;
  361.  
  362.   procedure shellsort(n: integer);
  363.     const
  364.       m = 3;   { total number of sort passes }
  365.     var
  366.       i: array[1..m] of integer;
  367.       j, k, p, s, t, incr: integer;
  368.     begin
  369.       i[m] := 1;
  370.       for j := m - 1 downto 1 do i[j] := 2 * i[j];
  371.       for j := 1 to m do
  372.         begin
  373.           incr := i[j];
  374.           for k := 1 to incr do
  375.             begin
  376.               s := incr + k;
  377.               while s <= n do
  378.                 begin
  379.                   p := s;
  380.                   t := thearray[p];
  381.                   thearray[k-incr] := t;
  382.                   while t < thearray[p-incr] do
  383.                     begin
  384.                       thearray[p] := thearray[p-incr];
  385.                       dec(p, incr);
  386.                     end;
  387.                   thearray[p] := t;
  388.                   inc(s, incr);
  389.                 end;
  390.             end;
  391.         end;
  392.     end;
  393.  
  394.   begin
  395.     randomize;
  396.     write('The unsorted array is: ');
  397.     for i := 1 to 20 do
  398.       begin
  399.         thearray[i] := random(50) + 1;
  400.         write(thearray[i], ' ');
  401.       end;
  402.     writeln;
  403.  
  404.     shellsort(20);  { 20 is high end of array }
  405.  
  406.     write('The sorted array is: ');
  407.     for i := 1 to 20 do
  408.       write(thearray[i], ' ');
  409.     writeln;
  410.   end.
  411. To get it to sort in ascending order instead of descending order, change the
  412. line:
  413.  
  414. while t < a[p-inc] do
  415.  
  416. to
  417.  
  418. while t > a[p-inc] do
  419.  
  420. Practice
  421. ========
  422. You should practice using these sorting methods.  They stay basically as
  423. indicated for any use, except for changing the identities of the item
  424. type in the array we sort.  For strings, we can alphabetize them by using
  425. the strings in the sorting routine for ascending order.  Look at the ASCII
  426. chart...It sees characters as numbers... a < b < c ...et al...  With
  427. strings, be sure to sort them case insensitively, especially, if we
  428. alphabetize a list or something like that....
  429.  
  430. Next Time
  431. =========
  432. We will cover methods of searching an array for data.  send comments to
  433. ggrotz@2sprint.net
  434.  
  435.   
  436.